﻿#include "ssWriteBytes.h"
#include "../ssAssert.h"

namespace StarSeeker
{

ssWriteBytes::ssWriteBytes()
:m_isResize(false)
{
}

ssWriteBytes::ssWriteBytes(u32 size, bool isResize)
:m_isResize(false)
{
	Set(size, isResize);
}

ssWriteBytes::ssWriteBytes(char* buffer, u32 size)
:m_isResize(false)
{
	Set(buffer, size);
}

ssWriteBytes::ssWriteBytes(const ssWriteBytes& wb)
:m_isResize(false)
{
	CopyFrom(wb);
}

ssWriteBytes::~ssWriteBytes()
{
	Clear();
}

void ssWriteBytes::operator=(const ssWriteBytes& wb)
{
	CopyFrom(wb);
}

bool ssWriteBytes::Set(u32 size, bool isResize)
{
	if(!m_buffer.Buf())
	{
		m_isResize = isResize;
		return m_buffer.Init(size);
	}
	return false;
}

bool ssWriteBytes::Set(char* buffer, u32 size)
{
	if(buffer && !m_buffer.Buf())
	{
		m_isResize = false;
		return m_buffer.Init(buffer, size);
	}
	return false;
}

bool ssWriteBytes::WriteString(const char* psz, ulint len)
{
	if (!m_isResize && len+cg_u32_size+m_buffer.Size() > m_buffer.MaxSize())
	{
		SS_ASSERT_DEBUG(false);
		return false;
	}
	WriteBuffer(&len, cg_u32_size);
	if (len>0)
	{
		WriteBuffer(psz, len);
	}
	return true;
}

bool ssWriteBytes::WriteString(std::string& str)
{
	return WriteString(str.c_str(), str.size());
}

bool ssWriteBytes::WriteStruct(const void* pbuf, ulint len)
{
	if (!m_isResize && len+cg_u32_size+m_buffer.Size() > m_buffer.MaxSize())
	{
		SS_ASSERT_DEBUG(false);
		return false;
	}
	WriteBuffer(&len, cg_u32_size);
	if (len>0)
	{
		WriteBuffer(pbuf, len);
	}
	return true;
}

void ssWriteBytes::Clear()
{
	m_isResize = false;
	m_buffer.Clear();
}

bool ssWriteBytes::WriteBuffer(const void* p, ulint size)
{
	if (size+m_buffer.Size() <= m_buffer.MaxSize())
	{
		memmove(m_buffer.CurrentBuf(), p, size);
		m_buffer.AddSize(size);
		return true;
	}
	else if (m_isResize && m_buffer.Resize((m_buffer.MaxSize()+size)*2, true))
	{
		memcpy(m_buffer.CurrentBuf(), p, size);
		m_buffer.AddSize(size);
		return true;
	}
	SS_ASSERT_DEBUG(false);
	return false;
}

void ssWriteBytes::CopyFrom(const ssWriteBytes& wb)
{
	m_buffer = wb.m_buffer;
	m_isResize = wb.m_isResize;
}

}
